package cn.turboinfo.fuyang.api.domain.common.handler.shop;


import cn.turboinfo.fuyang.api.domain.common.service.company.HousekeepingCompanyService;
import cn.turboinfo.fuyang.api.domain.common.service.division.DivisionService;
import cn.turboinfo.fuyang.api.domain.common.service.file.FileAttachmentService;
import cn.turboinfo.fuyang.api.domain.common.service.site.SiteUrlService;
import cn.turboinfo.fuyang.api.domain.util.PhoneUtils;
import cn.turboinfo.fuyang.api.domain.util.SecurityUtils;
import cn.turboinfo.fuyang.api.domain.util.UsernameUtils;
import cn.turboinfo.fuyang.api.domain.web.component.file.FileRefTypeConstant;
import cn.turboinfo.fuyang.api.entity.common.pojo.company.HousekeepingCompany;
import cn.turboinfo.fuyang.api.entity.common.pojo.division.Division;
import cn.turboinfo.fuyang.api.entity.common.pojo.file.FileAttachment;
import cn.turboinfo.fuyang.api.entity.common.pojo.shop.HousekeepingShop;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.*;

@RequiredArgsConstructor
@Component
public class ShopDataFactory {

    private final HousekeepingCompanyService housekeepingCompanyService;

    private final FileAttachmentService fileAttachmentService;

    private final SiteUrlService siteUrlService;

    private final DivisionService divisionService;

    @Value("${kit.security.rsa.public-key:}")
    private String base64RSAPublicKey;

    public void assembleCompany(List<HousekeepingShop> shopList) {

        Set<Long> companyIdSet = shopList.stream()
                .map(HousekeepingShop::getCompanyId)
                .collect(Collectors.toSet());

        Map<Long, HousekeepingCompany> companyMap = housekeepingCompanyService.findByIdCollection(companyIdSet)
                .stream()
                .collect(Collectors.toMap(HousekeepingCompany::getId, Function.identity()));

        shopList
                .stream()
                .peek(it -> {
                    if (companyMap.containsKey(it.getCompanyId())) {
                        it.setCompanyName(companyMap.get(it.getCompanyId()).getName());
                    }
                })
                .toList();
    }

    // 组装企业信息
    public HousekeepingShop assembleCompany(HousekeepingShop shop) {
        val company = housekeepingCompanyService.getByIdEnsure(shop.getCompanyId());

        shop.setCompanyName(company.getName());
        return shop;
    }

    public void assembleAttachment(List<HousekeepingShop> shopList) {
        Set<Long> shopIdSet = shopList.stream()
                .map(HousekeepingShop::getId)
                .collect(Collectors.toSet());

        // 门店图片
        List<FileAttachment> fileAttachmentList = fileAttachmentService.findByRefIdInAndRefType(shopIdSet, FileRefTypeConstant.SHOP_IMG)
                .stream()
                .peek(it -> it.setExternalUrl(siteUrlService.getUploadExternalImgUrl(it.getRelativePath())))
                .toList();

        // 图片文件编码集合
        Map<Long, List<Long>> imgFileIdMap = fileAttachmentList
                .stream()
                .filter(it -> it.getRefType().equals(FileRefTypeConstant.SHOP_IMG))
                .collect(groupingBy(FileAttachment::getRefId, collectingAndThen(toList(), list -> list.stream()
                        .map(FileAttachment::getId)
                        .collect(toList()))));

        // 营业执照
        List<FileAttachment> businessLicenseFileAttachmentList = fileAttachmentService.findByRefIdInAndRefType(shopIdSet, FileRefTypeConstant.SHOP_ATTACH)
                .stream()
                .peek(it -> it.setExternalUrl(siteUrlService.getUploadExternalImgUrl(it.getRelativePath())))
                .toList();

        // 营业执照名称集合
        Map<Long, List<String>> businessLicenseFileIdMap = businessLicenseFileAttachmentList
                .stream()
                .filter(it -> it.getRefType().equals(FileRefTypeConstant.SHOP_ATTACH))
                .collect(groupingBy(FileAttachment::getRefId, collectingAndThen(toList(), list -> list.stream()
                        .map(FileAttachment::getDisplayName)
                        .toList())));

        shopList.stream()
                .peek(it -> {
                    // 图片列表
                    if (imgFileIdMap.containsKey(it.getId())) {
                        it.setImgList(imgFileIdMap.get(it.getId()));
                    }
                    // 营业执照
                    if (businessLicenseFileIdMap.containsKey(it.getId())) {
                        it.setBusinessLicenseFileName(businessLicenseFileIdMap.get(it.getId()).get(0));
                    }
                })
                .toList();
    }

    public HousekeepingShop assembleAttachment(HousekeepingShop shop) {

        val id = shop.getId();

        // 门店图片
        List<FileAttachment> fileAttachmentList = fileAttachmentService.findByRefIdAndRefType(id, FileRefTypeConstant.SHOP_IMG)
                .stream()
                .peek(it -> it.setExternalUrl(siteUrlService.getUploadExternalImgUrl(it.getRelativePath())))
                .toList();


        // 营业执照
        List<FileAttachment> businessLicenseFileAttachmentList = fileAttachmentService.findByRefIdAndRefType(id, FileRefTypeConstant.SHOP_ATTACH)
                .stream()
                .peek(it -> it.setExternalUrl(siteUrlService.getUploadExternalImgUrl(it.getRelativePath())))
                .toList();

        // 图片列表
        if (!fileAttachmentList.isEmpty()) {
            shop.setImgList(fileAttachmentList.stream().map(FileAttachment::getId).collect(toList()));
        }
        // 营业执照
        if (!businessLicenseFileAttachmentList.isEmpty()) {
            shop.setBusinessLicenseFile(businessLicenseFileAttachmentList.get(0).getId());
            shop.setBusinessLicenseFileName(businessLicenseFileAttachmentList.get(0).getDisplayName());
        }
        return shop;
    }

    public void assembleAreaName(List<HousekeepingShop> shopList) {

        Set<Long> areaCodeSet = shopList.stream()
                .map(HousekeepingShop::getAreaCode)
                .collect(Collectors.toSet());

        Map<Long, Division> divisionMap = divisionService.findByIdCollection(areaCodeSet)
                .stream()
                .collect(Collectors.toMap(Division::getAreaCode, Function.identity()));

        shopList.stream()
                .peek(it -> {
                    // 地区
                    if (divisionMap.containsKey(it.getAreaCode())) {
                        it.setAreaName(divisionMap.get(it.getAreaCode()).getAreaName());
                    }

                })
                .toList();
    }

    public HousekeepingShop assembleAreaName(HousekeepingShop shop) {
        val division = divisionService.getByIdEnsure(shop.getAreaCode());
        shop.setAreaName(division.getAreaName());
        return shop;
    }

    public void maskInfo(List<HousekeepingShop> shopList) {
        shopList.stream()
                .peek(this::maskInfo)
                .toList();
    }

    public void maskInfo(HousekeepingShop shop) {
        shop.setContactMobileEncrypt(SecurityUtils.encodeBase64(SecurityUtils.encryptRSA(shop.getContactMobile().getBytes(), SecurityUtils.decodeBase64(base64RSAPublicKey))));
        shop.setContactMobile(PhoneUtils.maskPhoneNum(shop.getContactMobile()));
        shop.setContactPerson(UsernameUtils.maskUsername(shop.getContactPerson()));

    }
}
